package com.gddb.xwj.mywiki.controller;

import com.alibaba.fastjson.JSONObject;
import com.gddb.xwj.mywiki.req.UserLoginReq;
import com.gddb.xwj.mywiki.req.UserQueryReq;
import com.gddb.xwj.mywiki.req.UserResetPasswordReq;
import com.gddb.xwj.mywiki.req.UserSaveReq;
import com.gddb.xwj.mywiki.resp.CommonResp;
import com.gddb.xwj.mywiki.resp.PageResp;
import com.gddb.xwj.mywiki.resp.UserLoginResp;
import com.gddb.xwj.mywiki.resp.UserQueryResp;
import com.gddb.xwj.mywiki.service.UserService;
import com.gddb.xwj.mywiki.util.SnowFlake;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.concurrent.TimeUnit;

/**
 * 描述：用户管理（拷贝电子书管理模板）
 *
 * @author xwj
 * @create 2022-03-18 19:17
 */
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private SnowFlake snowFlake;

    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/list")
    public CommonResp list(UserQueryReq req){
        CommonResp<PageResp<UserQueryResp>> resp = new CommonResp<>();
        PageResp<UserQueryResp> cont = userService.list(req);
        resp.setContent(cont);
        return resp;
    }

    @PostMapping("/save")
    public CommonResp save(@Valid @RequestBody UserSaveReq req){
        req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes()));
        CommonResp resp = new CommonResp<>();
        userService.save(req);
        return resp;
    }

    /**
     * /{id} 用 @PathValiable接收
     * JSON 用 @RequestBody接收
     * @return
     */
    @DeleteMapping("/delete/{id}")
    public CommonResp delete(@PathVariable Long id){
        CommonResp<Object> resp = new CommonResp<>();
        userService.delete(id);
        return resp;
    }

    @PostMapping("/reset-password")
    public CommonResp resetPassword(@Valid @RequestBody UserResetPasswordReq req){
        req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes()));
        CommonResp resp = new CommonResp<>();
        userService.resetPassword(req);
        return resp;
    }

    @PostMapping("/login")
    public CommonResp login(@Valid @RequestBody UserLoginReq req) {
        req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes()));
        CommonResp<UserLoginResp> resp = new CommonResp<>();
        UserLoginResp userLoginResp = userService.login(req);

        //使用雪花算法生成的唯一ID作为token
        Long token = snowFlake.nextId();
        userLoginResp.setToken(token.toString());
        //token为key  响应json串为值 存放redis
        //特别说明 远程传输如存放redis 是需要序列化的 方式一是序列化 方式二是转成json字符串
        redisTemplate.opsForValue().set(token.toString(),JSONObject.toJSONString(userLoginResp),24*60*60, TimeUnit.SECONDS);
        log.info("key:{},value:{}",token.toString(),JSONObject.toJSONString(userLoginResp));
        resp.setContent(userLoginResp);
        return resp;
    }

    @GetMapping("/logout/{token}")
    public CommonResp logout(@PathVariable String token) {
        CommonResp resp = new CommonResp<>();
        redisTemplate.delete(token);
        log.info("从redis中删除token: {}", token);
        return resp;
    }

    /**
     * 解决 redis  key为\xac\xed\x00\x05t\x00\x10+token问题
     * 直接重写在此即可
     * @param redisTemplate
     */
    @Autowired(required = false)
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        RedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(stringSerializer);
        this.redisTemplate = redisTemplate;
    }
}
